package com.example.demospringboot.netty.http.service.impl;

import com.example.demospringboot.netty.http.HttpProperties;
import com.example.demospringboot.netty.http.handler.HttpClientInitializer;
import com.example.demospringboot.netty.http.handler.HttpResponseHandler;
import com.example.demospringboot.netty.http.service.HttpService;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.FullHttpResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author chenlei
 * @date 2020/1/8
 * @description
 **/
public class HttpServiceImpl implements HttpService {

    private Logger logger = LoggerFactory.getLogger(getClass());

    private Bootstrap bootstrap;

    private HttpProperties httpProperties;

    private HttpClientInitializer httpClientInitializer;

    public HttpServiceImpl(HttpProperties httpProperties) {
        this.httpProperties = httpProperties;
    }

    @Override
    public FullHttpResponse send(FullHttpRequest request) throws Exception {
        connect(request);
        HttpClientInitializer httpClientInitializer = (HttpClientInitializer) bootstrap.config().handler();
        FullHttpResponse result = httpClientInitializer.getHttpResponseHandler().getReceiveMsg();
        return result;
    }

    public void connect(FullHttpRequest request) {
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        request.headers().set(org.apache.http.HttpHeaders.CONTENT_TYPE,"text/plain;charset:utf-8");
        request.headers().set(org.springframework.http.HttpHeaders.CONTENT_LENGTH,request.content().readableBytes());
        try {
            Bootstrap bootstrap = new Bootstrap();
            httpClientInitializer = new HttpClientInitializer();
            httpClientInitializer.setHttpResponseHandler(new HttpResponseHandler());
            this.bootstrap = bootstrap;
            bootstrap.group(workerGroup)
                    .channel(NioSocketChannel.class)
                    .handler(httpClientInitializer)
                    .option(ChannelOption.SO_KEEPALIVE, true);
            ChannelFuture future = bootstrap.connect(httpProperties.getUrl(), httpProperties.getPort()).sync();
            future.channel().writeAndFlush(request).sync();
            future.channel().closeFuture().sync();
        } catch (InterruptedException e) {
            logger.error(e.getMessage());
        } finally {
            workerGroup.shutdownGracefully();
        }
    }

}
